package com.second_kill.second_kill_app.service;

import com.second_kill.second_kill_app.pool.SecondKillData;
import com.second_kill.second_kill_app.pool.ThreadPoolTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * Created by fangjicai on 2020/4/29.
 */

@Service
public class SecondKillService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

//    @Autowired
//    private SecondKillData secondKillData;

    public boolean secondKill(String userId,String kill_shop){
        boolean flag=false;
        //设置开启事务支持
        redisTemplate.setEnableTransactionSupport(true);
        //设置需要监听的key集合,包括库存kill_shop，和秒杀成功用户集合
        List<String> watchs = Arrays.asList(kill_shop,"user_list");
        //监听库存和秒杀成功的用户集合，如果有改变则事务执行失败
        redisTemplate.watch(watchs);
        //获取秒杀库存
       String num = redisTemplate.opsForValue().get(kill_shop);
        int secondKillStore = Integer.parseInt(num);

        if(secondKillStore>0){
            try {
                //开启事物
                redisTemplate.multi();
                //减库存操作
                redisTemplate.opsForValue().decrement(kill_shop);
                //维护秒杀成功的用户集合 定义集合key为user_list
                redisTemplate.opsForList().leftPush("user_list",userId);
                //提交事务
                List<Object> result = redisTemplate.exec();
                //结果不为null，说明提交成功
                if(result!=null){
                    //异步同步秒杀信息到mysql数据库，扣减库存生成秒杀订单
                    //方案1：连接mq，发送商品ID和秒杀成功用户ID(最优方案 开启一个线程异步处理)
//                    this.secondKillData.setUserId(userId);
//                    this.secondKillData.setShopId(kill_shop);
//                    ThreadPoolTools.execute(this.secondKillData);
                    //方案2：写一个具备有效期的定时任务，该任务与秒杀开始、结束时间一直，然后
                    //定时连接redis从user_list中获取秒杀成功的用户和对应的商品ID，
                    // 完成同步操作
                    flag=true;
                }
            } catch (Exception e) {
                //事务回滚
                redisTemplate.discard();
                flag=false;
            }
        }
        return flag;
    }


}
